import { IConvertParser, IPlugIn, ITableData } from "../../../inters/InterfaceApi";
import { convertMgr } from "../../mgr/ConvertMgr";
import { errLogMgr } from "../../mgr/ErrLogMgr";
import { IKeyVo, KeyVoUtil } from "../../utils/KeyVoUtil";

export class ErrorChecker implements IPlugIn {

    private _curtTable: ITableData;
    private _primaryKeys: string[];
    start(data: any, options?: any, callback?: (res?: any) => void) {
        let conv = convertMgr.crtConvert;
        for (let name in conv.tableData) {
            let td = conv.tableData[name];
            this._curtTable = td;
            if(!td.data)continue;
            this._primaryKeys = td.data.primaryKey ? td.data.primaryKey.split(",") : [];
            let values = td.data.list || [];
            let errors = [];
            td.keys.forEach(keyVo => {
                if (!(keyVo.content && keyVo.content.temp)) {
                    return;
                }
                for (var j = 0; j < values.length; j++) {
                    if (!values[j][keyVo.name]) {
                        continue;
                    }
                    var errorLog = "";
                    try {
                        if (keyVo.content.temp.indexOf("$") == 0) {
                            this._checkTemp(keyVo.content.temp, values[j][keyVo.name], this._getKeys(values[j]), keyVo.name, errors);
                        } else {
                            this._checkTemp(JSON.parse(keyVo.content.temp), values[j][keyVo.name], this._getKeys(values[j]), keyVo.name, errors);
                        }
                    } catch (e) {
                        errorLog = keyVo.name + "temp模板配置错误";
                        break;
                    }
                    if (errorLog) {
                        errLogMgr.addLog([errorLog])
                    }
                }
            })
            if(errors.length>0){
                errors.unshift(td.tableName + ":" + td.plat + "------------------------------------------------------")
                errLogMgr.addLog(errors);
            }
        }
    }

    protected _checkTemp(temp: any, value: any, primaryKey: string, keyName: string, logs: string[]) {
        if (!value) return;
        let rep = new RegExp(/\$([a-zA-Z]+)\$/);
        let rep2 = new RegExp(/\%([^\"]*)\%/);// /\%([^\"]*)\%/g
        if (typeof temp == "string" && temp.indexOf("$") == 0) {
            if (temp.indexOf('|') >= 0) {
                let tempList: string[] = temp.split('|');
                let ts = tempList.map(t => {
                    let re = rep.exec(t);
                    let key = rep2.exec(t);
                    if (re) {
                        if (key && key[1]) {
                            return re[1] + '|' + key[1];
                        }
                        return re[1];
                    }
                    return null;
                }).filter(t => !!t);
                this._checkTableDataExist(ts, this._curtTable.plat, value, primaryKey, keyName, logs);
            } else {
                let result = rep.exec(temp);
                let key = rep2.exec(temp);
                if (result) {
                    let re = result[1];
                    if (key && key[1]) {
                        re = result[1] + '|' + key[1];
                    }
                    this._checkTableDataExist(re, this._curtTable.plat, value, primaryKey, keyName, logs);
                }
            }
        } else {
            if (temp instanceof Array) {
                if (temp.length == 0) {
                    throw new Error("模板数据错误");
                }
                for (var i = 0; i < value.length; i++) {
                    // 这里修改可以使用 temp:["$SkillCell$","$PropCell$"] 这种方式来检查多个表的模板
                    this._checkTemp(temp[0], value[i], primaryKey, keyName, logs);
                }
            } else {
                for (let key in temp) {
                    this._checkTemp(temp[key], value[key], primaryKey, keyName, logs);
                }
            }
        }
    }

    protected _checkData(temp: string, keyVo: IKeyVo, vo: any) {
        let rep = new RegExp(/\$([a-zA-Z]+)\$/);
        var logs: any = [];
        var value = vo[keyVo.name];
        if (temp.indexOf("$") == 0) {
            let result = rep.exec(temp);
            if (result) {
                KeyVoUtil
                this._checkTableDataExist(result[1], this._curtTable.plat, value, this._getKeys(vo), keyVo.name, logs);
            }
        } else {
            var tempObj = JSON.parse(temp);
            if (tempObj instanceof Array) {
                if (tempObj.length == 0) {
                    throw new Error("模板数据错误");
                }
                for (let key in tempObj[0]) {
                    let result = rep.exec(temp);
                    if (result) {
                        for (var i = 0; i < value.length; i++) {
                            this._checkTableDataExist(result[1], this._curtTable.plat, value[i][key], this._getKeys(vo), keyVo.name, logs);
                        }
                    }
                }
            } else {
                for (let key in tempObj) {
                    let result = rep.exec(temp);
                    if (result) {
                        this._checkTableDataExist(result[1], this._curtTable.plat, value[key], this._getKeys(vo), keyVo.name, logs);
                    }
                }
            }
        }
        return logs.join("\r\n");
    }

    private _checkTableDataExist(table: string | string[], sh: string, key: string, primaryKey: string, keyName: string, logs: string[]) {
        if (typeof table == 'string') {
            if (table.indexOf('|') >= 0) {
                let tempTabs = table.split('|');
                let item = this._getTableData(tempTabs[0], sh, key.split(tempTabs[1])[0]);
                if (!item) {
                    logs.push(primaryKey + ":字段[" + keyName + "]数据中关联表<" + table + ">:" + key + "不存在");
                }
            } else {
                let item = this._getTableData(table, sh, key);
                if (!item) {
                    logs.push(primaryKey + ":字段[" + keyName + "]数据中关联表<" + table + ">:" + key + "不存在");
                }
            }
        } else {
            let finded = false;
            table.forEach(tab => {
                let item;
                if (tab.indexOf('|') >= 0) {
                    let tempTabs = tab.split('|');
                    item = this._getTableData(tempTabs[0], sh, key.split(tempTabs[1])[0]);
                } else {
                    item = this._getTableData(tab, sh, key);
                }
                if (item) finded = true;
            });
            if (!finded) {
                let tempTabName = table.join(' or ');
                logs.push(primaryKey + ":字段[" + keyName + "]数据中关联表<" + tempTabName + ">:" + key + "不存在");
            }
        }
    }
    private _getTableData(table: string, sh: string, key: string) {
        var tableItem: IConvertParser = convertMgr.crtConvert.getParser(table, sh);
        if (!tableItem) {
            tableItem = convertMgr.crtConvert.getParser(table);
        }
        if (tableItem) {
            return tableItem.getData(key);
        }
        return null;
    }

    protected _getKeys(d: any) {
        return KeyVoUtil.getRealKey(d, this._primaryKeys);
    }
}